package ar.com.gals.service;

import java.util.List;

import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import ar.com.gals.domain.Usuario;
import ar.com.gals.error.GalsException;
import ar.com.gals.repository.UsuarioRepository;
import ar.com.gals.security.SecurityUser;


@Service("userDetailsService")
public class UsuarioService extends AbstractService<Usuario> implements UserDetailsService {

	public UsuarioService() {
		this.domain = Usuario.class;
	}

	
	@Override
	@Transactional(readOnly = true)
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		
		try 
		{
			Usuario user = this.getByName(username);
			
			if(user == null)
				throw new GalsException("No existe el usuario ingresado");

			return new SecurityUser(user);
		} 
		catch (GalsException e) 
		{
			throw new UsernameNotFoundException(e.getErrors().get(0).getDescripcion());
		}
	}

	
	public List<Usuario> getAllNegocios(String codigo, String razonSocial) throws GalsException {
		
		List<Usuario> list = null;
		
		try
		{
			this.beginTransaction();
		
			list = new UsuarioRepository(this.session).getAllNegocios(codigo, razonSocial);
			
			this.commit();
		}
		catch(Exception e) {
			
			this.rollback();
			
			throw new GalsException(e.getMessage());
		}
		
		return list; 
	}
	


	public List<Usuario> getAllEmpleados(Usuario empleador, String nombre, String apellido) throws GalsException {

		List<Usuario> list = null;
		
		try
		{
			this.beginTransaction();
		
			list = new UsuarioRepository(this.session).getAllEmpleados(empleador, nombre, apellido);
			
			this.commit();
		}
		catch(Exception e) {
			
			this.rollback();
			
			throw new GalsException(e.getMessage());
		}
		
		return list; 
	}
	

	public Usuario getByName(String username) throws GalsException {
		
		Usuario user = null;
		
		try
		{
			this.beginTransaction();
		
			user = new UsuarioRepository(this.session).getByName(username);
			
			this.commit();
		}
		catch(Exception e) {
			
			this.rollback();
			
			throw new GalsException(e.getMessage());
		}
		
		return user;
	}
	
	
	@Override
	public void executeCreate(Usuario usuario) throws GalsException {
		
		if(usuario.isNegocio())
			this.validarCodigo(usuario);
		
		this.validarNombreDeUsuario(usuario);
		
		super.executeCreate(usuario);
	}
	
	
	@Override
	public void executeUpdate(Usuario usuario) throws GalsException {
		
		if(usuario.isNegocio())
			this.validarCodigo(usuario);
		
		this.validarNombreDeUsuario(usuario);
		
		if(usuario.isNegocio()) {
			
			UsuarioRepository repository = new UsuarioRepository(this.session);
			
			for(Usuario empleado : repository.getAllEmpleados(usuario, "", "")) {			
				empleado.setEnabled(usuario.isEnabled());
				repository.update(empleado);
			}
		}
		
		super.executeUpdate(usuario);
	}
	
	
	@Override
	public void executeDelete(Usuario usuario) throws GalsException {
		
		if(usuario.isNegocio()) {
			
			UsuarioRepository repository = new UsuarioRepository(this.session);
			
			for(Usuario empleado : repository.getAllEmpleados(usuario, "", "")) {			
				
				repository.delete(empleado);
			}
		}
		
		super.executeDelete(usuario);
	}


	private void validarCodigo(Usuario usuario) throws GalsException {
		
		Usuario usuario2 = new UsuarioRepository(this.session).getByCodigo(usuario.getCodigo());
		
		if(usuario2 != null && usuario.getId() != usuario2.getId())
			throw new GalsException("ya existe un usuario con codigo " + usuario.getCodigo());		
	}


	private void validarNombreDeUsuario(Usuario usuario) throws GalsException {
		
		if(!usuario.getNombreUsuario().equals(usuario.getNombreUsuario().toLowerCase()))
			throw new GalsException("el nombre de usuario debe ser en min&uacute;scula.");
		
		if(!usuario.getNombreUsuario().equals(usuario.getNombreUsuario().trim().replace(" ", "")))
			throw new GalsException("el nombre de usuario no puede contener espacios.");
		
		Usuario usuario2 = new UsuarioRepository(this.session).getByName(usuario.getNombreUsuario());
		
		if(usuario2 != null && usuario.getId() != usuario2.getId())
			throw new GalsException("ya existe un usuario con nombre " + usuario.getNombreUsuario());
	}
	
}
